#pragma once

#include <cstddef>

namespace sdu {

/**
 * 静态矩阵类示例。需要在编译期就确定矩阵尺寸。
 * T是类型参数。行数R、列数C是非类型参数。
*/
template <typename T, size_t R, size_t C>
class StaticMatrix {
  T* m_elems;

 public:
  StaticMatrix() : m_elems(new T[R * C]) {}

  ~StaticMatrix() { delete[] m_elems; }

  T* operator(size_t row) { return m_elems + C * row; }

  /**
   * 静态矩阵的优点是能在编译期就检测出无法运算的情况。
   * 左侧：<T,R,C>
   * 右侧：<T,C,W>
   * 结果：<T,R,W>
   * 两个运算数和结果可以是不同的类型。
  */
  template <size_t W>
  StaticMatrix<T, R, W> operator*(const StaticMatrix<T, C, W>& B) const {
    const StaticMatrix<T, R, W>& A = *this;
    StaticMatrix<T, R, W> C;
    for(size_t i = 0; i < R; ++i) {
      for(size_t j = 0; j < W; ++j) {
        T t = 0;
        for(size_t k = 0; k < C; ++k) {
          t += A[i][k] * B[k][j];
        }
        C[i][j] = t;
      }
    }
    return p;
  }
};

} // namespace sdu
